package models

import (
	"errors"
	"gitee.com/ha666/golibs"
	"strconv"
)

type Logininfo struct {
	LogId     int64  //登录日志编号
	UserId    int64  //用户编号
	SourceId  int    //来源编码（1系统）
	AppKey    int    //AppKey
	BuildPath string //目标路径
	IP        string //登录IP地址
	UserAgent string //UserAgent
	LoginTime int64  //登录时间
}

func ExistLogininfo(LogId int64) (bool, error) {
	rows, err := Ha666DBConn.Query("select count(0) Count from logininfo where LogId=?", LogId)
	if err != nil {
		return false, err
	}
	if len(rows) <= 0 {
		return false, nil
	}
	for _, obj := range rows {
		count, err := strconv.Atoi(string(obj["Count"]))
		if err != nil {
			return false, errors.New("parse Count error: " + err.Error())
		}
		return count > 0, nil
	}
	return false, nil
}

func InsertLoginInfoByTrans(userinfo Userinfo, logininfo Logininfo) (issuccess bool, errmsg string) {
	session := Ha666DBConn.NewSession()
	defer session.Close()
	err := session.Begin()
	if err != nil {
		return false, err.Error()
	}
	issuccess = false
	defer func() {
		if !issuccess {
			session.Rollback()
		}
	}()
	result1, err := session.Exec("update userinfo set UserNick=?,Password=?,Slat=?,Mobile=?,LastLoginIP=?,Status=?,LoginTime=? where UserId=? and Email=?", userinfo.UserNick, userinfo.Password, userinfo.Slat, userinfo.Mobile, userinfo.LastLoginIP, userinfo.Status, userinfo.LoginTime, userinfo.UserId, userinfo.Email)
	if err != nil {
		return false, "Rollback10:" + err.Error()
	}
	affected1, err := result1.RowsAffected()
	if err != nil {
		return false, "Rollback11"
	}
	if affected1 <= 0 {
		return false, "Rollback12"
	}
	result2, err := session.Exec("INSERT logininfo(UserId,SourceId,AppKey,BuildPath,IP,UserAgent,LoginTime) VALUES(?,?,?,?,?,?,?)", logininfo.UserId, logininfo.SourceId, logininfo.AppKey, logininfo.BuildPath, logininfo.IP, logininfo.UserAgent, logininfo.LoginTime)
	if err != nil {
		return false, "Rollback20" + err.Error()
	}
	affected2, err := result2.LastInsertId()
	if err != nil {
		return false, "Rollback21"
	}
	if affected2 <= 0 {
		return false, "Rollback22"
	}
	err = session.Commit()
	if err != nil {
		return false, "Rollback30" + err.Error()
	}
	issuccess = true
	return true, ""
}

func InsertLogininfo(logininfo Logininfo) (int64, error) {
	result, err := Ha666DBConn.Exec("insert into logininfo(UserId,SourceId,AppKey,BuildPath,IP,UserAgent,LoginTime) values(?,?,?,?,?,?,?)", logininfo.UserId, logininfo.SourceId, logininfo.AppKey, logininfo.BuildPath, logininfo.IP, logininfo.UserAgent, logininfo.LoginTime)
	if err != nil {
		return -1, err
	}
	return result.LastInsertId()
}

func UpdateLogininfo(logininfo Logininfo) (bool, error) {
	result, err := Ha666DBConn.Exec("update logininfo set UserId=?, SourceId=?, AppKey=?, BuildPath=?, IP=?, UserAgent=?, LoginTime=? where LogId=?", logininfo.UserId, logininfo.SourceId, logininfo.AppKey, logininfo.BuildPath, logininfo.IP, logininfo.UserAgent, logininfo.LoginTime, logininfo.LogId)
	if err != nil {
		return false, err
	}
	affected, err := result.RowsAffected()
	if err != nil {
		return false, err
	}
	return affected > 0, nil
}

func InsertUpdateLogininfo(logininfo Logininfo) (bool, error) {
	result, err := Ha666DBConn.Exec("insert into logininfo(UserId,SourceId,AppKey,BuildPath,IP,UserAgent,LoginTime) values(?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE UserId=?,SourceId=?,AppKey=?,BuildPath=?,IP=?,UserAgent=?,LoginTime=?", logininfo.UserId, logininfo.SourceId, logininfo.AppKey, logininfo.BuildPath, logininfo.IP, logininfo.UserAgent, logininfo.LoginTime, logininfo.UserId, logininfo.SourceId, logininfo.AppKey, logininfo.BuildPath, logininfo.IP, logininfo.UserAgent, logininfo.LoginTime)
	if err != nil {
		return false, err
	}
	affected, err := result.RowsAffected()
	if err != nil {
		return false, err
	}
	return affected > 0, nil
}

func GetLogininfo(LogId int64) (logininfo Logininfo, err error) {
	rows, err := Ha666DBConn.Query("select LogId, UserId, SourceId, AppKey, BuildPath, IP, UserAgent, LoginTime from logininfo where LogId=?", LogId)
	if err != nil {
		return logininfo, err
	}
	if len(rows) <= 0 {
		return logininfo, nil
	}
	logininfos, err := _LogininfoRowsToArray(rows)
	if err != nil {
		return logininfo, err
	}
	return logininfos[0], nil
}

// idx_logininfo_userid_logintime
func GetLogininfoByUserIdLoginTime(UserId int64, LoginTime int64) (logininfos []Logininfo, err error) {
	rows, err := Ha666DBConn.Query("select LogId, UserId, SourceId, AppKey, BuildPath, IP, UserAgent, LoginTime from logininfo where userid=? and logintime=?", UserId, LoginTime)
	if err != nil {
		return logininfos, err
	}
	if len(rows) <= 0 {
		return logininfos, nil
	}
	return _LogininfoRowsToArray(rows)
}

func GetLoginInfoByUserIdLoginTime(user_id int64, page_index, page_size int) (logininfos []Logininfo, err error) {
	rows, err := Ha666DBConn.Query("select LogId,UserId,SourceId,AppKey,BuildPath,IP,UserAgent,LoginTime from logininfo where UserId=? order by LoginTime desc LIMIT ?,?", user_id, (page_index-1)*page_size, page_size)
	if err != nil {
		return logininfos, err
	}
	if len(rows) <= 0 {
		return logininfos, nil
	}
	return _LogininfoRowsToArray(rows)
}

// idx_logininfo_appkey_logintime
func GetLogininfoByAppKeyLoginTime(AppKey int, LoginTime int64) (logininfos []Logininfo, err error) {
	rows, err := Ha666DBConn.Query("select LogId, UserId, SourceId, AppKey, BuildPath, IP, UserAgent, LoginTime from logininfo where appkey=? and logintime=?", AppKey, LoginTime)
	if err != nil {
		return logininfos, err
	}
	if len(rows) <= 0 {
		return logininfos, nil
	}
	return _LogininfoRowsToArray(rows)
}

// idx_logininfo_logintime
func GetLogininfoByLoginTime(LoginTime int64) (logininfos []Logininfo, err error) {
	rows, err := Ha666DBConn.Query("select LogId, UserId, SourceId, AppKey, BuildPath, IP, UserAgent, LoginTime from logininfo where logintime=?", LoginTime)
	if err != nil {
		return logininfos, err
	}
	if len(rows) <= 0 {
		return logininfos, nil
	}
	return _LogininfoRowsToArray(rows)
}

func GetLogininfoRowCount() (count int, err error) {
	rows, err := Ha666DBConn.Query("select count(0) Count from logininfo")
	if err != nil {
		return -1, err
	}
	if len(rows) <= 0 {
		return -1, nil
	}
	for _, obj := range rows {
		count, err := strconv.Atoi(string(obj["Count"]))
		if err != nil {
			return -1, errors.New("parse Count error: " + err.Error())
		}
		return count, nil
	}
	return -1, nil
}

// idx_logininfo_userid_logintime
func GetLogininfoRowListByUserIdLoginTime(UserIdIsDesc bool, LoginTimeIsDesc bool, PageIndex, PageSize int) (logininfos []Logininfo, err error) {
	sqlstr := golibs.NewStringBuilder()
	sqlstr.Append("select LogId, UserId, SourceId, AppKey, BuildPath, IP, UserAgent, LoginTime from logininfo order by")
	sqlstr.Append(" UserId")
	if UserIdIsDesc {
		sqlstr.Append(" Desc")
	}
	sqlstr.Append(",")
	sqlstr.Append(" LoginTime")
	if LoginTimeIsDesc {
		sqlstr.Append(" Desc")
	}
	sqlstr.Append(" limit ?,?")
	rows, err := Ha666DBConn.Query(sqlstr.ToString(), (PageIndex-1)*PageSize, PageSize)
	sqlstr.Append(",")
	if err != nil {
		return logininfos, err
	}
	if len(rows) <= 0 {
		return logininfos, nil
	}
	return _LogininfoRowsToArray(rows)
}

// idx_logininfo_appkey_logintime
func GetLogininfoRowListByAppKeyLoginTime(AppKeyIsDesc bool, LoginTimeIsDesc bool, PageIndex, PageSize int) (logininfos []Logininfo, err error) {
	sqlstr := golibs.NewStringBuilder()
	sqlstr.Append("select LogId, UserId, SourceId, AppKey, BuildPath, IP, UserAgent, LoginTime from logininfo order by")
	sqlstr.Append(" AppKey")
	if AppKeyIsDesc {
		sqlstr.Append(" Desc")
	}
	sqlstr.Append(",")
	sqlstr.Append(" LoginTime")
	if LoginTimeIsDesc {
		sqlstr.Append(" Desc")
	}
	sqlstr.Append(" limit ?,?")
	rows, err := Ha666DBConn.Query(sqlstr.ToString(), (PageIndex-1)*PageSize, PageSize)
	sqlstr.Append(",")
	if err != nil {
		return logininfos, err
	}
	if len(rows) <= 0 {
		return logininfos, nil
	}
	return _LogininfoRowsToArray(rows)
}

// idx_logininfo_logintime
func GetLogininfoRowListByLoginTime(LoginTimeIsDesc bool, PageIndex, PageSize int) (logininfos []Logininfo, err error) {
	sqlstr := golibs.NewStringBuilder()
	sqlstr.Append("select LogId, UserId, SourceId, AppKey, BuildPath, IP, UserAgent, LoginTime from logininfo order by")
	sqlstr.Append(" LoginTime")
	if LoginTimeIsDesc {
		sqlstr.Append(" Desc")
	}
	sqlstr.Append(" limit ?,?")
	rows, err := Ha666DBConn.Query(sqlstr.ToString(), (PageIndex-1)*PageSize, PageSize)
	sqlstr.Append(",")
	if err != nil {
		return logininfos, err
	}
	if len(rows) <= 0 {
		return logininfos, nil
	}
	return _LogininfoRowsToArray(rows)
}

func _LogininfoRowsToArray(maps []map[string][]byte) ([]Logininfo, error) {
	models := make([]Logininfo, len(maps))
	var err error
	for index, obj := range maps {
		model := Logininfo{}
		model.LogId, err = strconv.ParseInt(string(obj["LogId"]), 10, 64)
		if err != nil {
			return nil, errors.New("parse LogId error: " + err.Error())
		}
		model.UserId, err = strconv.ParseInt(string(obj["UserId"]), 10, 64)
		if err != nil {
			return nil, errors.New("parse UserId error: " + err.Error())
		}
		model.SourceId, err = strconv.Atoi(string(obj["SourceId"]))
		if err != nil {
			return nil, errors.New("parse SourceId error: " + err.Error())
		}
		model.AppKey, err = strconv.Atoi(string(obj["AppKey"]))
		if err != nil {
			return nil, errors.New("parse AppKey error: " + err.Error())
		}
		model.BuildPath = string(obj["BuildPath"])
		model.IP = string(obj["IP"])
		model.UserAgent = string(obj["UserAgent"])
		model.LoginTime, err = strconv.ParseInt(string(obj["LoginTime"]), 10, 64)
		if err != nil {
			return nil, errors.New("parse LoginTime error: " + err.Error())
		}
		models[index] = model
	}
	return models, err
}
